package com.java.base.thread;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalTime;
import java.util.Date;
import java.util.concurrent.*;

public class ThreadPoolExecutorTest {

    public static void runtime() {
        int s = 1024 * 1024;
        long m = Runtime.getRuntime().maxMemory() / s;
        int p = Runtime.getRuntime().availableProcessors();
        long tm = Runtime.getRuntime().totalMemory() / s;
        System.out.println("m:" + m + "mb");
        System.out.println("tm:" + tm + "mb");
        System.out.println("p:" + p);
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        delayQueue();
    }

    public static void delayQueue() throws InterruptedException {
        DelayQueue<DDelay> delayQueue = new DelayQueue<>();

        delayQueue.offer(new DDelay(LocalTime.now().toString(),10000));

        System.out.println(delayQueue.take());

    }

    public static class DDelay implements Delayed {

        String data;
        long start;

        public DDelay(String data, long start) {
            this.data = data;
            this.start = System.currentTimeMillis() + start;
        }

        @Override
        public long getDelay(TimeUnit unit) {

            Date date = new Date();

//            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
//                return simpleDateFormat.parse("2021-06-22 14:11:00").getTime();
                return unit.convert(start - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
            } catch (Exception e) {
                e.printStackTrace();
            }

            return 10;
        }

        @Override
        public int compareTo(Delayed o) {
            return (int) (this.getDelay(TimeUnit.SECONDS) - o.getDelay(TimeUnit.SECONDS));
        }

        @Override
        public String toString() {
            return "DDelay{" +
                    "data='" + data + '\'' +
                    ", start=" + start +
                    '}';
        }
    }

    public static void forkJoinPool() {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        ForkJoinTask<String> f = new RecursiveTask<String>() {
            @Override
            protected String compute() {
                return "END";
            }
        };

    }

    public static void future() throws ExecutionException, InterruptedException {
        FutureTask<String> f1 = new FutureTask<>(() -> {
            Thread.sleep(10000);
            return "END";
        });

        new Thread(f1).start();


        while (!f1.isDone()) {
            System.out.println("NOT DONE");
            Thread.sleep(1000);
        }

        System.out.println(f1.get());

    }


    public static void Executors2() throws InterruptedException {
        ThreadPoolExecutor executorService = new ThreadPoolExecutor(
                1, 1
                , 10, TimeUnit.SECONDS
                , new PrintLinkedBlockingQueue<>(1));
        executorService.execute(() -> {
            try {
                System.out.println(Thread.currentThread().hashCode());
//                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        Thread.sleep(1000);

        executorService.submit(() -> System.out.println(Thread.currentThread().hashCode()));

        executorService.shutdown();
    }

    public static class PrintLinkedBlockingQueue<E> extends LinkedBlockingQueue<E> {

        public PrintLinkedBlockingQueue(int capacity) {
            super(capacity);
        }

        @Override
        public boolean offer(E e) {
            System.out.println("offer:" + e);
            return super.offer(e);
        }

        @Override
        public E poll(long timeout, TimeUnit unit) throws InterruptedException {
            E e = super.poll(timeout, unit);
            System.out.println("poll:" + e);
            return e;
        }

        @Override
        public E take() throws InterruptedException {
            E e = super.take();
            System.out.println("take:" + e);
            return e;
        }


    }


}
